package com.mkx.service.impl;

import com.mkx.model.LoginRequest;
import com.mkx.model.TokenResponse;
import com.mkx.security.JwtTokenProvider;
import com.mkx.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 认证服务实现类
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${jwt.expiration}")
    private long jwtExpiration;

    @Override
    public TokenResponse login(LoginRequest loginRequest) {
        // 验证登录类型
        if ("platform".equals(loginRequest.getLoginType())) {
            // 平台管理员登录逻辑
            return authenticatePlatformUser(loginRequest);
        } else if ("tenant".equals(loginRequest.getLoginType())) {
            // 租户用户登录逻辑
            return authenticateTenantUser(loginRequest);
        } else {
            throw new IllegalArgumentException("Invalid login type");
        }
    }

    /**
     * 认证平台管理员用户
     */
    private TokenResponse authenticatePlatformUser(LoginRequest loginRequest) {
        // 实际项目中应该使用Spring Security的认证管理器进行认证
        // 这里简化处理，仅作为示例
        if (!"admin".equals(loginRequest.getUsername()) || !"admin123".equals(loginRequest.getPassword())) {
            throw new IllegalArgumentException("Invalid username or password");
        }

        // 模拟用户ID和权限信息
        String userId = "1";
        String role = "PLATFORM_ADMIN";
        String[] permissions = {"USER_MANAGE", "TENANT_MANAGE", "ROLE_MANAGE", "PERMISSION_MANAGE"};

        return generateTokenResponse(userId, loginRequest.getUsername(), null, role, permissions);
    }

    /**
     * 认证租户用户
     */
    private TokenResponse authenticateTenantUser(LoginRequest loginRequest) {
        // 验证租户ID是否存在
        if (loginRequest.getTenantId() == null || loginRequest.getTenantId().isEmpty()) {
            throw new IllegalArgumentException("Tenant ID is required for tenant login");
        }

        // 实际项目中应该使用Spring Security的认证管理器进行认证
        // 这里简化处理，仅作为示例
        if (!"tenant_user".equals(loginRequest.getUsername()) || !"tenant123".equals(loginRequest.getPassword())) {
            throw new IllegalArgumentException("Invalid username or password");
        }

        // 模拟用户ID和权限信息
        String userId = "2";
        String role = "TENANT_ADMIN";
        String[] permissions = {"USER_MANAGE", "ROLE_MANAGE", "PERMISSION_MANAGE"};

        return generateTokenResponse(userId, loginRequest.getUsername(), loginRequest.getTenantId(), role, permissions);
    }

    /**
     * 生成令牌响应
     */
    private TokenResponse generateTokenResponse(String userId, String username, String tenantId, String role, String[] permissions) {
        // 生成访问令牌和刷新令牌
        String accessToken = tokenProvider.generateToken(userId, username, tenantId, role, permissions);
        String refreshToken = tokenProvider.generateRefreshToken(userId, tenantId);

        // 将令牌存储到Redis中，用于登出等操作
        storeTokenInRedis(userId, accessToken);

        // 构建响应
        TokenResponse response = new TokenResponse();
        response.setAccessToken(accessToken);
        response.setRefreshToken(refreshToken);
        response.setExpiresIn(jwtExpiration / 1000); // 转换为秒

        // 设置用户信息
        TokenResponse.UserInfo userInfo = new TokenResponse.UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUsername(username);
        userInfo.setTenantId(tenantId);
        userInfo.setRole(role);
        userInfo.setPermissions(permissions);
        response.setUserInfo(userInfo);

        return response;
    }

    /**
     * 将令牌存储到Redis
     */
    private void storeTokenInRedis(String userId, String token) {
        String key = "token:" + userId;
        redisTemplate.opsForValue().set(key, token, jwtExpiration, TimeUnit.MILLISECONDS);
    }

    @Override
    public TokenResponse refreshToken(String refreshToken) {
        // 实际项目中应该验证刷新令牌的有效性
        // 这里简化处理，仅作为示例
        // 模拟从刷新令牌中提取用户信息
        String userId = "1";
        String username = "admin";
        String tenantId = null;
        String role = "PLATFORM_ADMIN";
        String[] permissions = {"USER_MANAGE", "TENANT_MANAGE", "ROLE_MANAGE", "PERMISSION_MANAGE"};

        return generateTokenResponse(userId, username, tenantId, role, permissions);
    }

    @Override
    public void logout(String token) {
        // 从Redis中删除令牌
        // 实际项目中应该从令牌中提取用户ID
        String userId = "1"; // 简化处理
        String key = "token:" + userId;
        redisTemplate.delete(key);
    }
}